﻿#include "ccnotepad.h"
#include "nddsetting.h"
#include "styleset.h"
#include "syntaxthememanager.h"
#include "systemthemedetector.h"
#include "qtlangset.h"
#include <Qsci/qscilexer.h>


#include <QtWidgets/QApplication>
// Qt6 使用 QStringConverter 替代 QTextCodec
#include <QStringConverter>
#include <QMessageBox>
#include <QSharedMemory>
#include <QFile>
#include <QStatusBar>
#include <qobject.h>
#include <QThread>
#include <QDir>
#include <QMutex>
#include <QMutexLocker>
#include <QMetaObject>
#include <QFontDatabase>

#ifdef Q_OS_UNIX
#include <QStyleFactory>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <QDebug>
#include <QWidget>
#include <QScreen>
#ifdef WAYLAND_SUPPORT
#include <QGuiApplication>
#include <qpa/qplatformnativeinterface.h>
#endif
#ifdef DBUS_SUPPORT
#include <QDBusConnection>
#include <QDBusInterface>
#endif
#endif

#ifdef Q_OS_WIN
#pragma comment(lib, "user32.lib")
#if _DEBUG
	#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
		#pragma comment(lib, "qmyedit_qt6d.lib")
	#else
		#pragma comment(lib, "qmyedit_qt5d.lib")
	#endif
#else
	#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
		#pragma comment(lib, "qmyedit_qt6.lib")
	#else
		#pragma comment(lib, "qmyedit_qt5.lib")
	#endif
#endif
#include <qt_windows.h>
const ULONG_PTR CUSTOM_TYPE = 10000;
const ULONG_PTR OPEN_NOTEPAD_TYPE = 10001;
const ULONG_PTR CUSTOM_TYPE_FILE_LINENUM = 10002;
bool s_isAdminAuth = false;
#endif

const QString c_strTitle = "Ndd";


#ifdef Q_OS_UNIX
#if defined(Q_OS_MAC)
QSharedMemory shared("CCNotebook123");;//mac下面后面带一个版本号，避免新的打不开
#else
QSharedMemory shared("CCNotebook");
#endif
QSharedMemory nppShared("notepad--");

// Wayland/Linux下使用全局指针，因为QWidget::find在Wayland下不可用
#ifndef Q_OS_MAC
static CCNotePad* g_mainWindow = nullptr;
static QMutex g_windowMutex; // 保护全局指针的线程安全
#endif

static void sig_usr(int signo)
{
    if(signo  == SIGUSR1)
    {
#ifdef Q_OS_MAC
        qlonglong winId;
        shared.lock();
        memcpy(&winId,shared.data(),sizeof(qlonglong));
        shared.unlock();

        QWidget *pMain = QWidget::find((WId)winId);
        CCNotePad* pNotePad = dynamic_cast<CCNotePad*>(pMain);
#else
        // Linux: 使用全局指针（同时支持Wayland和X11）
        QMutexLocker locker(&g_windowMutex);
        CCNotePad* pNotePad = g_mainWindow;
#endif

        if(pNotePad != nullptr)
        {
            // 安全地读取共享内存数据
            QString filePath;
            if(nppShared.isAttached())
            {
                nppShared.lock();
                // 确保数据以null结尾，防止越界
                char buffer[1024] = {0};
                memcpy(buffer, (char*)nppShared.data()+sizeof(pid_t), sizeof(buffer)-1);
                buffer[sizeof(buffer)-1] = '\0';
                filePath = QString::fromUtf8(buffer);
                nppShared.unlock();
            }

            if(!filePath.isEmpty())
            {
                // 使用QMetaObject::invokeMethod确保在主线程中调用
                QMetaObject::invokeMethod(pNotePad, [pNotePad, filePath]() {
                    pNotePad->openFile(filePath);
                    pNotePad->activateWindow();
                    pNotePad->raise();
                    pNotePad->showNormal();
                }, Qt::QueuedConnection);
                qDebug() << "sig_usr: scheduled file open:" << filePath;
            }
            else
            {
                QMetaObject::invokeMethod(pNotePad, [pNotePad]() {
                    pNotePad->activateWindow();
                    pNotePad->raise();
                    pNotePad->showNormal();
                }, Qt::QueuedConnection);
                qDebug() << "sig_usr: activating window";
            }
        }
        else
        {
            qDebug() << "Warning: Main window not found in signal handler";
        }
    }
}
#endif

#ifdef Q_OS_MAC

static void openfile(QString filePath)
{

    qlonglong winId;
    shared.lock();
    memcpy(&winId,shared.data(),sizeof(qlonglong));
    shared.unlock();

     QWidget *pMain = QWidget::find((WId)winId);
     CCNotePad* pNotePad = dynamic_cast<CCNotePad*>(pMain);
     if(pNotePad != nullptr)
     {
         if(!filePath.isEmpty())
         {
            pNotePad->openFile(filePath);
         }
         pNotePad->activateWindow();
         pNotePad->showNormal();
     }
}

class MyApplication : public QApplication
{
   public:
       MyApplication(int &argc, char **argv)
           : QApplication(argc, argv)
       {
       }

       bool event(QEvent *event)
       {
           if (event->type() == QEvent::FileOpen) {
               QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
               qDebug() << "Open file" << openEvent->file();
               s_openfile = openEvent->file();
               openfile(s_openfile);
           }

           return QApplication::event(event);
       }
       QString s_openfile;
   };
#endif

int main(int argc, char *argv[])
{
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
	// 支持Wayland和X11平台
	// 设置环境变量以增强Wayland兼容性和稳定性
	#ifdef WAYLAND_SUPPORT
	if (qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM")) {
		// Qt会自动检测可用的平台（wayland或xcb）
		// 不强制指定平台，让Qt自动选择最佳的
	}

	// 防止Wayland/GNOME下的闪退问题
	// 关键：让Qt使用物理DPI而非逻辑DPI，避免缩放冲突
	if (qEnvironmentVariableIsEmpty("QT_WAYLAND_FORCE_DPI")) {
		qputenv("QT_WAYLAND_FORCE_DPI", "physical");
	}

	// 支持4K/8K高分屏：启用自动缩放
	if (qEnvironmentVariableIsEmpty("QT_AUTO_SCREEN_SCALE_FACTOR")) {
		qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
	}

	// 如果Wayland不可用，自动回退到X11（防止闪退）
	if (qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM")) {
		qputenv("QT_QPA_PLATFORMTHEME", "qt5ct");  // 优先使用qt5ct主题
	}

	// GNOME特定：防止OpenGL相关闪退
	// 在某些GNOME版本中，强制使用软件渲染可以避免GPU驱动问题
	if (qEnvironmentVariableIsEmpty("QT_XCB_GL_INTEGRATION")) {
		// 不强制设置，让Qt自动选择最佳选项
		// qputenv("QT_XCB_GL_INTEGRATION", "none");
	}

	// 让Qt自动检测DPI，以支持4K/8K等高分辨率显示器的缩放
	// 移除了强制DPI=96的设置，避免在高分屏上界面过小
	#endif
#endif

	// 高DPI支持配置 - 支持4K(3840x2160)、5K、8K(7680x4320)显示器
	// Qt6 默认启用高DPI支持
	// 设置屏幕缩放因子策略为 PassThrough，支持分数缩放
	QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);

#ifdef Q_OS_MAC
    MyApplication a(argc, argv);
#else
	QApplication a(argc, argv);
#endif

	//不能开启，开启后相对路径打开文件失败
	//QDir::setCurrent(QCoreApplication::applicationDirPath());

#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
	// 检测当前使用的平台插件
	QString platformName = QGuiApplication::platformName();
	qDebug() << "Platform:" << platformName;
	
	// 获取屏幕信息以调试高DPI问题
	QScreen *primaryScreen = QGuiApplication::primaryScreen();
	if (primaryScreen) {
		qDebug() << "Screen resolution:" << primaryScreen->size();
		qDebug() << "Screen physical size:" << primaryScreen->physicalSize() << "mm";
		qDebug() << "Screen DPI:" << primaryScreen->logicalDotsPerInch() << "logical,"
		         << primaryScreen->physicalDotsPerInch() << "physical";
		qDebug() << "Device pixel ratio:" << primaryScreen->devicePixelRatio();
	}

	#ifdef WAYLAND_SUPPORT
	if (platformName == "wayland") {
		qDebug() << "Running on Wayland";
		// Wayland特定设置
		QGuiApplication::setDesktopFileName("io.gitee.cxasm.notepad--");

		// 防止Wayland/GNOME闪退的关键措施
		a.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);

		// 禁用不稳定的特性，提高稳定性
		a.setAttribute(Qt::AA_DontUseNativeMenuBar);

		// 确保窗口管理器正确识别应用
		qputenv("QT_WAYLAND_SHELL_INTEGRATION", "xdg-shell");

		// 对于GNOME：禁用某些可能导致崩溃的优化
		const char* desktopEnv = getenv("XDG_CURRENT_DESKTOP");
		if (desktopEnv && QString(desktopEnv).contains("GNOME", Qt::CaseInsensitive)) {
			qDebug() << "Running on GNOME, applying stability fixes";
			// GNOME特定的稳定性设置
			a.setAttribute(Qt::AA_DisableShaderDiskCache);
		}
	} else if (platformName == "xcb") {
		qDebug() << "Running on X11";
		// X11下也支持高DPI
	} else {
		qDebug() << "Running on unknown platform:" << platformName;
	}
	#else
	qDebug() << "Wayland support not compiled in, running on:" << platformName;
	#endif
	
    QApplication::setStyle(QStyleFactory::create("fusion"));
#endif

#ifdef Q_OS_MAC
	// macOS也支持Fusion样式（Qt5.2+），提供更统一的跨平台UI体验
	// Fusion样式在macOS上提供了更现代的外观
	QApplication::setStyle(QStyleFactory::create("fusion"));
#endif
	a.setApplicationDisplayName(c_strTitle);
	a.setApplicationName(c_strTitle);

	// 加载内置的 Source Code Pro 字体 / Load embedded Source Code Pro font
	int fontIdRegular = QFontDatabase::addApplicationFont(":/fonts/SourceCodePro-Regular.ttf");
	int fontIdBold = QFontDatabase::addApplicationFont(":/fonts/SourceCodePro-Bold.ttf");

	if (fontIdRegular != -1)
	{
		QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontIdRegular);
		if (!fontFamilies.isEmpty())
		{
			QString sourceCodeProFamily = fontFamilies.at(0);
			qDebug() << "Loaded Source Code Pro font (Regular + Bold):" << sourceCodeProFamily;
		}
	}

	QStringList arguments = QCoreApplication::arguments();

	//目前就三种
	//1) ndd filepath
	//2) ndd filepath -n linenum
	//3) ndd -multi filepath
	//只有 1  2 需要处理短路径
	if ((arguments.size() == 2) || (arguments.size() == 4))
	{
		QFileInfo fi(arguments[1]);
		if (fi.isRelative())
		{
			QString absDir = QDir::currentPath();
			//获取绝对路径
			arguments[1] = QString("%1/%2").arg(absDir).arg(arguments.at(1));
		}
	}

	// 设置 Source Code Pro 为默认字体（所有平台统一使用） / Set Source Code Pro as default font for all platforms
	QFont defaultFont("Source Code Pro", 11);
	defaultFont.setStyleHint(QFont::Monospace);

#ifdef uos
	defaultFont.setPointSize(9);
	QApplication::setFont(defaultFont);
#endif
#ifdef Q_OS_MAC
	//这里的字体大小，务必要和查找结果框的高度匹配，否则会结构字体拥挤
	defaultFont.setPointSize(11);
	QApplication::setFont(defaultFont);
	qDebug() << "Default font set to:" << QApplication::font().toString();
#endif
#ifdef Q_OS_WIN
	defaultFont.setPointSize(10);
	QApplication::setFont(defaultFont);
#endif
#if !defined(uos) && !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
	// Linux 和其他 Unix 系统
	defaultFont.setPointSize(10);
	QApplication::setFont(defaultFont);
#endif

bool isGotoLine = false;

#ifdef Q_OS_WIN
	QSharedMemory shared("ccnotepad");

	if (arguments.size() > 2)
	{
		//如果是多开请求，这种是从管理员权限申请后重开过来的
		if (arguments[1] == QString("-muti"))
		{
			s_isAdminAuth = true;

			QString title = QString(u8"%1 管理员").arg(c_strTitle);
			a.setApplicationDisplayName(title);
			//删除-muti这个参数
			arguments.removeAt(1);
			
			//管理员不占用共享标志。这样的目的是，当管理员窗口存在时
			//打开原来的文件，原来的文件可以占用共享标志，作为主窗口打开。
			//管理员窗口永远不做主窗口打开
			goto authAdmin;
			
		}
		else if ((arguments.size() == 4) && arguments[2] == QString("-n"))
		{
			//使用的是 file -n lineNums 方式。目前只有windows下支持 xxxfile -n linenum的格式
			isGotoLine = true;
	}
		
	}
#else
if ((arguments.size() == 4) && (arguments[2] == QString("-n")))
{
      //使用的是 file -n lineNums 方式。目前只有windows下支持 xxxfile -n linenum的格式
      isGotoLine = true;
}
#endif

	//attach成功表示已经存在该内存了，表示当前存在实例
	if (shared.attach())//共享内存被占用则直接返回
	{
		qDebug() << "Found existing shared memory, checking if instance is valid...";

		//发现在文件中如果存在空格时，参数不止1个，所以不能单纯用2个参数表示
		if (arguments.size() > 1)
		{
        #if defined(Q_OS_WIN)
			int tryTimes = 0;
			do {
			qlonglong hwndId;
			shared.lock();
			memcpy(&hwndId, shared.data(), sizeof(qlonglong));
			shared.unlock();

			HWND hwnd = (HWND)hwndId;

			if (::IsWindow(hwnd))
			{
					if (!isGotoLine)
					{
						//就是ndd filepath的命令行格式
				//去掉第一个参数，后续的参数拼接起来。其实参数中间有空格还是需要使用""引用起来，避免空格参数分隔为多个
				arguments.takeFirst();

				QString filename = arguments.join("");
				QByteArray data = filename.toUtf8();

				COPYDATASTRUCT copydata;
				copydata.dwData = CUSTOM_TYPE; //自定义类型
				copydata.lpData = data.data();  //数据大小
				copydata.cbData = data.size();  // 指向数据的指针

				::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(&copydata));
			}
			else
			{
						//是 filepath -n linenums 方式。不考虑filepath含有空格的情况，因为前面做了严格判断
						
						QString para = QString("%1|%2").arg(arguments[1]).arg(arguments[3]);
						QByteArray data = para.toUtf8();

						COPYDATASTRUCT copydata;
						copydata.dwData = CUSTOM_TYPE_FILE_LINENUM; //自定义类型
						copydata.lpData = data.data();  //数据大小
						copydata.cbData = data.size();  // 指向数据的指针

						::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(&copydata));
					}

					break;
				}
				else
				{
					
					//20230304 右键多个文件同时打开，比如3个。此时只有第1个可获取锁，其余2个均走这里。
					//因为第个还没有来的及写入hwnd。此时不要goto drop_old。等一下再重试
					QThread::sleep(1); 
					++tryTimes;

					//2次识别后，没法了，只能通过继续往下走。
				//失败了，此时说明前一个窗口极可能状态错误了。如果不处理，则再也打不开程序了
					if (tryTimes > 2)
					{
				goto drop_old;
			}

				}
			} while (true);

        #elif defined (Q_OS_MAC)
        {
               //mac下面不需要，有他自身的机制保证
        }
        #else
            pid_t pid;

            arguments.takeFirst();
            QString filename = arguments.join("");
            QByteArray data = filename.toUtf8();

            if(!nppShared.attach())
            {
                qDebug() << "Failed to attach to shared memory, creating new instance";
                goto unix_goon;
            }

            nppShared.lock();
            memcpy(&pid, nppShared.data(), sizeof(pid_t));
            // 安全地写入文件名，确保不超出缓冲区
            size_t maxSize = 1024 - sizeof(pid_t) - 1;
            size_t copySize = qMin((size_t)data.size(), maxSize);
            memset((char*)nppShared.data()+sizeof(pid_t), 0, 1024-sizeof(pid_t));
            memcpy((char*)nppShared.data()+sizeof(pid_t), data.data(), copySize);
            nppShared.unlock();

            // 检查pid是否有效
            if(pid <= 0)
            {
                qDebug() << "Invalid pid in shared memory:" << pid << ", creating new instance";
                nppShared.detach();
                goto unix_goon;
            }

            // 先检查进程是否存在
            if(kill(pid, 0) != 0)
            {
                int err = errno;
                qDebug() << "Process" << pid << "does not exist (errno:" << err << "), creating new instance";
                nppShared.detach();
                goto unix_goon;
            }

            // 发送信号
            if(kill(pid, SIGUSR1) != 0)
            {
                int err = errno;
                qDebug() << "Failed to send signal to pid" << pid << "(errno:" << err << "), creating new instance";
                nppShared.detach();
                goto unix_goon;
            }

            qDebug() << "Successfully sent file to existing instance (pid:" << pid << ")";
        #endif
		}
		else if (arguments.size() == 1)
		{
#if defined(Q_OS_WIN)
			//把窗口设置到最前
			qlonglong hwndId;
			shared.lock();
			memcpy(&hwndId, shared.data(), sizeof(qlonglong));
			shared.unlock();
			HWND hwnd = (HWND)hwndId;
			if (::IsWindow(hwnd))
			{
				QString filename("open");
				QByteArray data = filename.toUtf8();

				COPYDATASTRUCT copydata;
				copydata.dwData = OPEN_NOTEPAD_TYPE; //自定义类型
				copydata.lpData = data.data();  //数据大小
				copydata.cbData = data.size();  // 指向数据的指针

				::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(&copydata));
			}
			else
			{
				//失败了，此时说明前一个窗口极可能状态错误了。如果不处理，则再也打不开程序了
				//继续新开一个窗口，放弃之前的旧内容
				goto drop_old;
			}
#elif defined (Q_OS_MAC)
{
       //mac下面不需要，有他自身的机制保证
}
#else
            pid_t pid = 0;

            if(!nppShared.attach())
            {
                qDebug() << "Failed to attach to shared memory, creating new instance";
                shared.detach();
                goto unix_goon;
            }

            nppShared.lock();
            memcpy(&pid, nppShared.data(), sizeof(pid_t));
            // 清空文件路径（无参数启动时只激活窗口）
            memset((char*)nppShared.data()+sizeof(pid_t), 0, 1024-sizeof(pid_t));
            nppShared.unlock();
            qDebug() << "Empty file send (activate window), pid:" << pid;

            // 检查pid是否有效（>0）且进程是否真的存在
            if(pid > 0 && kill(pid, 0) == 0)
            {
                // 进程存在，发送信号
                qDebug() << "Found valid process, sending signal to pid:" << pid;
                if(kill(pid, SIGUSR1) != 0)
                {
                    int err = errno;
                    qDebug() << "Failed to send signal (errno:" << err << "), creating new instance";
                    shared.detach();
                    nppShared.detach();
                    goto unix_goon;
                }
            }
            else
            {
                // pid无效或进程不存在，是残留的共享内存，继续创建新实例
                int err = errno;
                qDebug() << "Stale/invalid shared memory detected (pid:" << pid << ", errno:" << err << "), creating new instance";
                shared.detach();
                nppShared.detach();
                goto unix_goon;
            }
#endif
		}
		return 0;
	}
#if defined(Q_OS_WIN)
	shared.create(32);
#elif defined (Q_OS_MAC)
{
       //mac下面不需要，有他自身的机制保证。当程序已经在线时，再打开程序，系统会自动调用已经存在的程序出现
        //不需要使用类似linux下面的机制。
     shared.create(32);
     nppShared.create(32);
}
#else

unix_goon:
    shared.create(32);
    nppShared.create(2048);

    if(signal(SIGUSR1,sig_usr) == SIG_ERR)
    {
       qDebug()<<"linux create sign failed";
    }
#endif

#if defined(Q_OS_WIN)
authAdmin:
drop_old:
#endif

	//20221009发现有小概率出现窗口没有，但是进程还在的诡异问题，加个保护一下
	QApplication::setQuitOnLastWindowClosed(true);

	NddSetting::init();

	// 始终使用亮色主题
	NddSetting::updataKeyValueFromNumSets(THEME_MODE, 1);
	NddSetting::updataKeyValueFromNumSets(SKIN_KEY, DEFAULT_LIGHT);
	NddSetting::updataKeyValueFromNumSets(SYNTAX_THEME_KEY, SYNTAX_LIGHT);

	// 初始化UI主题（窗口、按钮、标签页等的外观）
	int savedSkinId = NddSetting::getKeyValueFromNumSets(SKIN_KEY);
	StyleSet::setSkin(savedSkinId);
	
	// 初始化语法主题（独立于UI主题，控制编辑器颜色）
	SyntaxThemeManager::instance()->loadThemeFromSettings();
	// loadThemeFromSettings() 会自动调用 applyEditorGlobalStyle() 设置编辑器颜色
	qDebug() << "Syntax theme initialized:" << SyntaxThemeManager::instance()->getCurrentSyntaxThemeName();
	
	// 设置QsciLexer的颜色调整回调函数（用于暗色主题下的语法高亮）
	QsciLexer::setColorAdjustCallback([](const QColor& color) -> QColor {
		return SyntaxThemeManager::instance()->mapLightColorToCurrentTheme(color);
	});

	CCNotePad *pMainNotepad = new CCNotePad(true);
	pMainNotepad->setAttribute(Qt::WA_DeleteOnClose);
	pMainNotepad->setShareMem(&shared);

	// 在主窗口创建后，根据主题模式应用主题（启动时检测一次）
	// 这样可以确保所有必需的全局状态已初始化
	StyleSet::applyThemeByMode();

	// 启用系统主题监听功能（如果设置为跟随系统）
	int themeMode = NddSetting::getKeyValueFromNumSets(THEME_MODE);
	if (themeMode == 0) { // 0 = 跟随系统
		SystemThemeDetector* themeDetector = new SystemThemeDetector(pMainNotepad);

		// 连接主题变化信号
		QObject::connect(themeDetector, &SystemThemeDetector::themeChanged,
			[pMainNotepad](bool isDark) {
				qDebug() << "System theme changed, applying new theme. Dark mode:" << isDark;

				// 延迟执行，确保系统主题完全更新
				QTimer::singleShot(500, [isDark, pMainNotepad]() {
					// 更新UI主题
					StyleSet::applyThemeByMode();
					pMainNotepad->updateThemes();

					// 智能更新语法主题以匹配系统主题
					SyntaxThemeManager* syntaxMgr = SyntaxThemeManager::instance();
					int currentSyntaxTheme = syntaxMgr->getCurrentSyntaxTheme();

					// 判断是否需要切换语法主题
					bool needSwitch = false;
					int targetTheme = currentSyntaxTheme;

					if (isDark && currentSyntaxTheme == SYNTAX_LIGHT) {
						// 系统切换到暗色，但语法主题是亮色，自动切换到暗色语法主题
						targetTheme = SYNTAX_DARK;
						needSwitch = true;
					} else if (!isDark && currentSyntaxTheme != SYNTAX_LIGHT) {
						// 系统切换到亮色，但语法主题不是亮色，自动切换到亮色语法主题
						targetTheme = SYNTAX_LIGHT;
						needSwitch = true;
					}

					if (needSwitch) {
						qDebug() << "Auto-switching syntax theme from"
								<< syntaxMgr->getSyntaxThemeName(currentSyntaxTheme)
								<< "to" << syntaxMgr->getSyntaxThemeName(targetTheme)
								<< "due to system theme change";
						syntaxMgr->setSyntaxTheme(targetTheme);
					} else {
						qDebug() << "Keeping current syntax theme:"
								<< syntaxMgr->getSyntaxThemeName(currentSyntaxTheme);
					}
				});
			});

		// 启动监听
		themeDetector->startWatching();
		qDebug() << "System theme watching enabled";
	}

	// 同步当前应用的主题到菜单
	int currentThemeId = NddSetting::getKeyValueFromNumSets(SKIN_KEY);
	pMainNotepad->syncCurSkinToMenu(currentThemeId);

	pMainNotepad->quickshow();

#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
	// 在Linux下保存主窗口指针（同时支持Wayland和X11）
	{
		QMutexLocker locker(&g_windowMutex);
		g_mainWindow = pMainNotepad;
	}

	// 确保程序退出时清理全局指针
	QObject::connect(pMainNotepad, &QObject::destroyed, []() {
		QMutexLocker locker(&g_windowMutex);
		g_mainWindow = nullptr;
		qDebug() << "Main window destroyed, cleared global pointer";
	});
#endif

#ifdef Q_OS_WIN
	//HWND hwnd = ::FindWindowA("Qt5QWindowIcon", "CCNotebook");
	//发现hwnd就是和effectiveWinId相等的，不需要查询了
	//管理员可以多开，暂时不把管理员的权限作为主窗口，因为其他用户没有权限右键菜单发送消息给管理员窗口去打开文件
	if (!s_isAdminAuth)
	{
	qlonglong winId = (qlonglong)pMainNotepad->effectiveWinId();
	shared.lock();
	memcpy(shared.data(), &winId, sizeof(qlonglong));
	shared.unlock();
	}
#else
    // Linux（包括X11和Wayland）
    qlonglong winId = (qlonglong)pMainNotepad->effectiveWinId();

    // 在Wayland下，窗口ID可能不可靠，但我们仍然保存它以保持兼容性
    // 实际的窗口查找通过全局指针 g_mainWindow 完成
    if(shared.isAttached() || shared.attach() || shared.create(32))
    {
        shared.lock();
        memcpy(shared.data(), &winId, sizeof(qlonglong));
        shared.unlock();
        qDebug() << "Saved window ID to shared memory:" << winId;
    }
    else
    {
        qDebug() << "Warning: Failed to create/attach shared memory for window ID";
    }

    // 获取进程ID并保存到共享内存（用于实例间通信）
    pid_t pid = getpid();
    if(!nppShared.isAttached())
    {
        nppShared.attach();
    }

    if(nppShared.isAttached())
    {
        nppShared.lock();
        memcpy(nppShared.data(), &pid, sizeof(pid_t));
        // 清空文件路径区域
        memset((char*)nppShared.data()+sizeof(pid_t), 0, 1024-sizeof(pid_t));
        nppShared.unlock();
        qDebug() << "Saved PID to shared memory:" << pid;
    }
    else
    {
        qDebug() << "Warning: Failed to attach to nppShared memory";
    }
#endif // Q_OS_WIN
	//恢复上次关闭时的文件
#ifdef Q_OS_WIN
	if (!s_isAdminAuth)
	{
		if (0 == pMainNotepad->restoreLastFiles() && (arguments.size() == 1))
		{
		pMainNotepad->initTabNewOne();
	}
	}
#else
    if (0 == pMainNotepad->restoreLastFiles())
    {
    pMainNotepad->initTabNewOne();
    }
#endif
	if (arguments.size() == 2)
	{
#ifdef Q_OS_WIN
		if (!s_isAdminAuth)
		{
			pMainNotepad->openFile(arguments[1]);
		}
		else
		{
			//如果是管理员，还不能直接打开文件，需要恢复之前文件的修改内容
			//恢复不了，再直接打开
			pMainNotepad->tryRestoreFile(arguments[1]);
		}
#else
		pMainNotepad->openFile(arguments[1]);
#endif
	}
	else if (isGotoLine)
	{
		//是filepath -n xxx 格式。
		bool ok = true;
		int lineNum = arguments[3].toInt(&ok);
		if (!ok)
		{
			lineNum = -1;
		}
		pMainNotepad->openFile(arguments[1], lineNum);
	}
#ifdef Q_OS_WIN
	pMainNotepad->checkAppFont();
#endif

	a.exec();

	NddSetting::close();

	return 0;
}
